package com.sjm.suchbear.bluetoothtest;

import android.Manifest;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import kr.co.namee.permissiongen.PermissionFail;
import kr.co.namee.permissiongen.PermissionGen;
import kr.co.namee.permissiongen.PermissionSuccess;

public class MainActivity extends Activity {

    @BindView(R.id.tv_openBT)
    TextView tvOpenBT;
    @BindView(R.id.tv_searchBT)
    TextView tvSearchBT;
    @BindView(R.id.ListView)
    MyListView ListView;
    @BindView(R.id.ListView_No)
    MyListView ListViewNo;
    @BindView(R.id.tv_server)
    TextView tvServer;
    @BindView(R.id.tv_send)
    TextView tvSend;
    @BindView(R.id.tv_goPic)
    TextView tvGoPic;

    private BluetoothAdapter BTadapter;
    private SearchReceiver msearchReceiver;
    private List<BluetoothDevice> connectedBlueTooths = new ArrayList<>();
    private List<BluetoothDevice> newBlueTooths = new ArrayList<>();
    private BlueToothListAdapter blueToothListAdapter;
    private BlueToothListAdapter blueToothListAdapterNo;
    private BluetoothSocket mclientSocket;
    private int mAutoConnectInterruptTime = 0;
    private boolean isConnect = false;
    public static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    private String name = "FIUBluetoothServer";
    private BluetoothServerSocket mserverSocket;
    private static String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        if (Build.VERSION.SDK_INT >= 6.0) {
            askPermission();
        }
        msearchReceiver = new SearchReceiver();

        ListViewNo.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                BluetoothDevice device = newBlueTooths.get(position);
                if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
                    try {
                        Method createBondMethod = BluetoothDevice.class.getMethod("createBond");
                        createBondMethod.invoke(device);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                ConnectThread connectThread = new ConnectThread(device);
                connectThread.start();
            }
        });

        ListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                BluetoothDevice device = connectedBlueTooths.get(position);
                if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
                    try {
                        Method createBondMethod = BluetoothDevice.class.getMethod("createBond");
                        createBondMethod.invoke(device);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                ConnectThread connectThread = new ConnectThread(device);
                connectThread.start();
            }
        });
    }

    private class ConnectThread extends Thread {
        private BluetoothDevice device;

        public ConnectThread(BluetoothDevice device) {
            this.device = device;
            try {
                mclientSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        public void run() {
            while (mAutoConnectInterruptTime < 5) {
                try {
                    mclientSocket.connect();
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            // TODO 显示连接成功
                            Toast.makeText(getBaseContext(), "连接成功", Toast.LENGTH_SHORT).show();
                        }
                    });
                    isConnect = true;
                    mAutoConnectInterruptTime = 0;
                    //manageConnectedSocket(socket); // 创建新的线程对蓝牙进行数据读取。
                    new ClientWorkingThread(mclientSocket).start();
                    break;
                } catch (IOException e) {
                    e.printStackTrace();
                    try {
                        mclientSocket = (BluetoothSocket) device.getClass().getMethod("createRfcommSocket", new Class[]{int.class}).invoke(device, 1);
                        mclientSocket.connect();
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(getBaseContext(), "连接成功", Toast.LENGTH_SHORT).show();
                            }
                        });
                        isConnect = true;
                        mAutoConnectInterruptTime = 0;
                        new ClientWorkingThread(mclientSocket).start();
                    } catch (Exception e2) {
                        e.printStackTrace();
                        mAutoConnectInterruptTime++;
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e1) {
                            e1.printStackTrace();
                        }

                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(getBaseContext(), "连接失败", Toast.LENGTH_SHORT).show();
                            }
                        });
                    }

                    // TODO 进行对 inputStream outputStream socket 进行关闭 置空.
                    return;
                }
            }

        }

        public void cancel() {
            try {
                mclientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 通过反射原理，发起蓝牙连接
     */
    public BluetoothSocket connectBtBySco(BluetoothDevice mBluetoothDevice) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, IOException {
        Method method = mBluetoothDevice.getClass().getMethod("createScoSocket");
        BluetoothSocket mBluetoothSocket = (BluetoothSocket) method.invoke(mBluetoothDevice);
        //mBluetoothSocket.connect();//发起连接
        return mBluetoothSocket;
    }


    private void askPermission() {
        PermissionGen.needPermission(MainActivity.this, 100, new String[]{
                Manifest.permission.BLUETOOTH_ADMIN,
                Manifest.permission.ACCESS_FINE_LOCATION
        });
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        PermissionGen.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
    }

    @PermissionSuccess(requestCode = 100)
    public void requestPhotoSuccess() {
    }

    @PermissionFail(requestCode = 100)
    public void requestPhotoFail() {
        //失败之后的处理
        Toast.makeText(getBaseContext(), "未同意授权，软件无法正常使用", Toast.LENGTH_SHORT).show();
        System.exit(0);
    }

    @OnClick({R.id.tv_openBT, R.id.tv_searchBT, R.id.tv_server, R.id.tv_send, R.id.tv_goPic})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.tv_openBT:
                try {
                    enableBlueTooth();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
            case R.id.tv_searchBT:
                searchBlueTooth();
                break;
            case R.id.tv_server:
                ServerThread serverThread = new ServerThread();
                serverThread.start();
                break;
            case R.id.tv_send:
                serverSend("我是猪猪啊哈哈");
                break;
            case R.id.tv_goPic:
                Intent intent = new Intent(this, CurveActivity.class);
                startActivity(intent);
                break;
        }
    }

    private class ServerThread extends Thread {
        @Override
        public void run() {
            try {
                enableBlueTooth();
                if (mserverSocket == null) {
                    mserverSocket = getDefaultAdapter(getBaseContext())
                            .listenUsingRfcommWithServiceRecord(name,
                                    MY_UUID);
                }
                isConnect = true;
                while (isConnect) {
                    mclientSocket = mserverSocket.accept();
                    myHandler.sendEmptyMessage(0x01);
                    new ClientWorkingThread(mclientSocket).start();
                    serverSend("你好");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    private Handler myHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            Toast.makeText(getBaseContext(),
                    "客户端已连接：" + mclientSocket.getRemoteDevice().getName(), Toast.LENGTH_SHORT)
                    .show();
        }

    };

    /**
     * 客户端socket工作类
     *
     * @author weizh
     */
    private class ClientWorkingThread extends Thread {
        /**
         * 客户端socket
         */
        private BluetoothSocket mClientSocket;

        public ClientWorkingThread(BluetoothSocket clientSocket) {
            this.mClientSocket = clientSocket;
        }

        @Override
        public void run() {
            try {
                InputStream inputStream = mClientSocket.getInputStream();// 输入流
                // 从输入流中取出数据，插入消息条中
                byte[] buffer = new byte[1024];
                while (isConnect) {
                    int read = inputStream.read(buffer);
                    if (read != -1) {
                        // 有内容
                        // 判断是否取得的消息填充满了buffer，未到字符串结尾符；如果不是，证明读取到了一条信息，并且信息是完整的，这个完整的前提是不能粘包，不粘包可以使用flush进行处理。
                        final StringBuilder sb = new StringBuilder();
                        if (read < buffer.length) {
                            String msg = new String(buffer, 0, read);
                            sb.append(msg);
                        } else {
                            byte[] tempBytes = new byte[1024 * 4];
                            while (read == buffer.length
                                    && buffer[read - 1] != 0x7f) {
                                read = inputStream.read(buffer);
                            }
                            String msg = new String(buffer, 0, read);
                            sb.append(msg);
                        }
                        Log.i(TAG, "服务器收到：" + sb.toString());
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(getBaseContext(), "收到了对面发来的消息哈哈：" + sb.toString(), Toast.LENGTH_SHORT).show();
                            }
                        });
                       /* synchronized (listMsg) {
                            listMsg.add("客户端发送：" + sb.toString());
                        }*/
                    }
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            // 工作完毕，关闭socket
            try {
                mClientSocket.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    /**
     * 服务端发送消息
     *
     * @param msg
     */
    public void serverSend(String msg) {
        if (mclientSocket != null) {
            try {
                mclientSocket.getOutputStream().write(msg.getBytes());
                mclientSocket.getOutputStream().flush();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }


    public static BluetoothAdapter getDefaultAdapter(Context context) {
        BluetoothAdapter adapter = null;
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            adapter = BluetoothAdapter.getDefaultAdapter();
        } else {
            final BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
            adapter = bluetoothManager.getAdapter();
        }
        return adapter;
    }


    public void enableBlueTooth() throws Exception {
        this.BTadapter = getDefaultAdapter(this);
        if (BTadapter == null) {
            throw new Exception("设备上没有发现有蓝牙设备");
        }
        if (!BTadapter.isEnabled()) {
            BTadapter.enable();
            Toast.makeText(this, "蓝牙已开启", Toast.LENGTH_SHORT).show();
        }
    }

    private void searchBlueTooth() {
        if (BTadapter == null) {
            this.BTadapter = getDefaultAdapter(this);
        }
        if (BTadapter.isDiscovering()) {
            BTadapter.cancelDiscovery();
        }
        IntentFilter iFilter = new IntentFilter();
        iFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        iFilter.addAction(BluetoothDevice.ACTION_FOUND);
        iFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        getBaseContext().registerReceiver(msearchReceiver, iFilter);
        BTadapter.startDiscovery();
    }

    private class SearchReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            switch (action) {
                case BluetoothAdapter.ACTION_DISCOVERY_STARTED:
                    connectedBlueTooths.clear();
                    newBlueTooths.clear();
                    break;
                case BluetoothDevice.ACTION_FOUND:
                    BluetoothDevice device = intent
                            .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    /*short rssi = intent.getExtras().getShort(
                            BluetoothDevice.EXTRA_RSSI);
                    Log.i("info", "蓝牙信号强度     " + rssi);*/
                    if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
                        for (BluetoothDevice bluetoothDevice : connectedBlueTooths) {
                            if (bluetoothDevice.getAddress().equals(
                                    device.getAddress()))
                                return;
                        }
                        connectedBlueTooths.add(device);
                    } else {
                        for (BluetoothDevice bluetoothDevice : newBlueTooths) {
                            if (bluetoothDevice.getAddress().equals(
                                    device.getAddress())) {
                                return;
                            }
                        }
                        newBlueTooths.add(device);
                    }
                    break;
                case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
                    blueToothListAdapter = new BlueToothListAdapter(getBaseContext(), connectedBlueTooths);
                    ListView.setAdapter(blueToothListAdapter);
                    blueToothListAdapterNo = new BlueToothListAdapter(getBaseContext(), newBlueTooths);
                    ListViewNo.setAdapter(blueToothListAdapterNo);
                    getBaseContext().unregisterReceiver(msearchReceiver);
                    break;

            }
        }
    }

}
